using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class GameController : BasePanel {
	
	private Misson misson;
	public static int ROW_NUM = 8;
	public static int COLUMN_NUM = 7;
	public static float ADD_NEW_ROW_TIME = 5.0f;
	private int score = 0;
	public static int CLEAR_UP_NUM = 3;
	
	public static int Player_Max_Count = 5;
	public UILabel timeLabel;
	public UILabel scoreLabel;
	public UISprite[] starList;
	public GameObject gameOver;
	
	public enum GameState{
		INIT = 0,
		INITING = 1,
		GAME = 2,
		CLEAR_UP = 3,
		CLEAR_UP_ANIMATION = 4,
		OVER = 6,
		
	}
	public GameState gameState = GameState.INIT;
	
	public Item[,] itemList = null;
	public GameObject itemTable;
	public GameObject itemPrefab;
	
	float time = ADD_NEW_ROW_TIME;
	float gameTime = 0.0f;
//	private bool isClearUp;
	public GameObject effectPrb;
	public GameHeroItem player;
	// Use this for initialization
	void Start () {
//		Init();
//		StartCoroutine(UpdateGame());
//		UpdateGame();
	}
	
	// Update is called once per frame
	void Update () {
		switch(gameState){
		case GameState.INIT:
			Init();
			gameState = GameState.INITING;
			break;
		case GameState.INITING:
			
			break;
		case GameState.GAME:
			UpdateGame();
			break;
		case GameState.CLEAR_UP_ANIMATION:
			UpdateAnimation();
			break;
		case GameState.CLEAR_UP:
			UpdateClearUp();
			break;
		case GameState.OVER:
			break;
		}
	}
//	public IEnumerator Test(){
//		Debug.Log("Test Start!");
//		itemList[0,0].SetItemType(Item.ITEM_TYPE.GREED);
//		Refresh();
//		yield return StartCoroutine(itemList[0,0].ClearUp());
//		Refresh();
//		Debug.Log("Test End!");
//	}
	public override void Refresh(){
		foreach(Item item in itemList){
			if((int)item.GetItemType() > 0){
				NGUITools.SetActiveChildren(item.gameObject,true);
			}else{
				NGUITools.SetActiveChildren(item.gameObject,false);
			}
		}
//		itemTable.repositionNow = true;
	}
	public override IEnumerator Init(){
		gameState = GameState.INITING;
		
		MissonManager missonMananger = (MissonManager)GameManager.GetInstatnce().GetManager(ManagerType.MISSION);
		misson = missonMananger.GetCurSelectMisson();
		
		gameTime = 0.0f;
		ClearItemList();
		score = 0;
		time = 0;
		NGUITools.SetActive(gameOver,false);
		itemList = new Item[ROW_NUM + Player_Max_Count,COLUMN_NUM];
		for(int i = 0;i < ROW_NUM + Player_Max_Count;i++){
			for(int j = 0;j < COLUMN_NUM;j++){
				GameObject itemObj = NGUITools.AddChild(itemTable,itemPrefab);
				Item item = itemObj.GetComponent<Item>();
				item.SetItemType(Item.ITEM_TYPE.NULL,i,j);
				itemList[i,j] = item;
				itemObj.transform.localPosition = new Vector3(j*78,-i*78,0);
				item.SetGameController(this);
				NGUITools.SetActiveChildren(itemObj,true);
			}
		}
//		itemTable.repositionNow = true;
//		for(int i = 0;i < ROW_NUM + Player_Max_Count;i++){
//			for(int j = 0;j < COLUMN_NUM;j++){
//				NGUITools.SetActive(itemList[i,j].gameObject,false);
//			}
//		}
		gameState = GameState.GAME;
		yield break;
	}
	void UpdateGame(){
//		while(true){
//		if(!isClearUp){
		time -= Time.deltaTime;
		if(time < 0.0f){
//				yield return new WaitForSeconds(5f);
			AddNewRow();
			time = ADD_NEW_ROW_TIME;
		}
		gameTime += Time.deltaTime;
		if(score >= misson.starScoreList[2] && gameTime /60 <= misson.starTimeList[2]){
			ToGameOver(3);
		}else if(score >= misson.starScoreList[1] && gameTime /60 <= misson.starTimeList[1]){
			ToGameOver(2);
		}else if(score >= misson.starScoreList[0] && gameTime /60 <= misson.starTimeList[0]){
			ToGameOver(1);
		}else if(gameTime /60 > misson.starTimeList[0]){
			gameTime = misson.starTimeList[0] * 60;
			ToGameOver(0);
		}
		timeLabel.text = ""+(misson.starTimeList[0] * 60 - gameTime).ToString("f2");
		scoreLabel.text = ""+ score.ToString();
//		}
//		yield return 1;
//		}
	}
	void AddNewRow(){
		for(int i = ROW_NUM;i > 0;i--){
			for(int j = 0;j < COLUMN_NUM;j++){
				itemList[i,j].SetItemType(itemList[i - 1,j].GetItemType());
			}
		}
		for(int j = 0;j < COLUMN_NUM;j++){
			int[] itemTypeList = misson.itemTypeList;
			int index = Random.Range(0,itemTypeList.Length);
			itemList[0,j].SetItemType((Item.ITEM_TYPE)itemTypeList[index]);
		}
		Refresh();
		if(IsField()){
			gameState = GameState.OVER;
			NGUITools.SetActive(gameOver,true);
		}
		gameState = GameState.CLEAR_UP;
//		StartClearUp();
//		yield return 0;
//		Refresh();
	}
	public void UpdateClearUp(){
		if(!JudClearUpAll()){
			gameState = GameState.GAME;
		}
	}
	public void ToGameOver(int star){
		gameState = GameState.OVER;
		NGUITools.SetActive(gameOver,true);
		misson.star = star;
		if(star == 3){
			NGUITools.SetActive(starList[0].gameObject,true);
			NGUITools.SetActive(starList[1].gameObject,true);
			NGUITools.SetActive(starList[2].gameObject,true);
		}else if(star == 2){
			NGUITools.SetActive(starList[0].gameObject,true);
			NGUITools.SetActive(starList[1].gameObject,true);
			NGUITools.SetActive(starList[2].gameObject,false);
		}else if(star == 1){
			NGUITools.SetActive(starList[0].gameObject,true);
			NGUITools.SetActive(starList[1].gameObject,false);
			NGUITools.SetActive(starList[2].gameObject,false);
		}else if(star == 0){
			NGUITools.SetActive(starList[0].gameObject,false);
			NGUITools.SetActive(starList[1].gameObject,false);
			NGUITools.SetActive(starList[2].gameObject,false);
		}
		if(star > 0){
			MissonManager manager = (MissonManager)GameManager.GetInstatnce().GetManager(ManagerType.MISSION);
			manager.OpenMisson(misson.id + 1);
		}
	}
	public void UpdateAnimation(){
		bool result = false;
		for(int i = 0;i < ROW_NUM + Player_Max_Count;i++){
			for(int j = 0;j < COLUMN_NUM;j++){
				if(itemList[i,j].IsAnimation){
					result = true;
				}
			}
		}
		if(!result){
			gameState = GameState.CLEAR_UP;
//			NGUITools.AddChild(gameObject,effectPrb).transform.localPosition = new Vector3(0,0,-100);
			
			ClearUpNull();
			Refresh();
//			AddNewItem();
//			Refresh();
		}
	}
	public void StartClearUp(){
//		isClearUp = true;
		gameState = GameState.CLEAR_UP;
		Refresh();
	}
	
	void OnGUI(){
		GUI.TextArea(new Rect(10,10,100,40),"Time:"+time);
	}
	public bool JudClearUpAll(){
		bool result = false;
		foreach(Item item in itemList){
			if(!item.IsNull()){
				bool resultTmp = false;
				resultTmp = JudClearUp(item.GetRow(),item.GetColumn());
				if(!result && resultTmp){
					result = resultTmp;
				}
			}
		}
		if(result){
			gameState = GameState.CLEAR_UP_ANIMATION;  
		}
		return result;
	}
	bool JudClearUp(int row,int colunm){
		Item item = itemList[row,colunm];
		if(item.GetItemType() == Item.ITEM_TYPE.NULL){
			return false;
		}else{
			List<Item> clearRowItemList = new List<Item>();
			List<Item> clearColumnItemList = new List<Item>();
			clearRowItemList.Add(item);
			clearColumnItemList.Add(item);
	
			//up
			int indexRow = row;
			while(indexRow > 0){
				indexRow--;
				if(itemList[indexRow,colunm].GetItemType() == item.GetItemType()){
					clearRowItemList.Add(itemList[indexRow,colunm]);
				}else{
					break;
				}
			}
			//down
			indexRow = row;
			while(indexRow < ROW_NUM + Player_Max_Count - 1){
				indexRow++;
				if(itemList[indexRow,colunm].GetItemType() == item.GetItemType()){
					clearRowItemList.Add(itemList[indexRow,colunm]);
				}else{
					break;
				}
			}
			//left
			int indexColunm = colunm;
			while(indexColunm > 0){
				indexColunm--;
				if(itemList[row,indexColunm].GetItemType() == item.GetItemType()){
					clearColumnItemList.Add(itemList[row,indexColunm]);
				}else{
					break;
				}
			}
			//right
			indexColunm = colunm;
			while(indexColunm < COLUMN_NUM - 1){
				indexColunm++;
				if(itemList[row,indexColunm].GetItemType() == item.GetItemType()){
					clearColumnItemList.Add(itemList[row,indexColunm]);
				}else{
					break;
				}
			}
			
			//clear up item
			bool result = false;
			if(clearRowItemList.Count >= CLEAR_UP_NUM){
				result = true;
				foreach(Item itemTmp in clearRowItemList){
//					yield return StartCoroutine( itemTmp.ClearUp());
				 	StartCoroutine(itemTmp.ClearUp());
				}
				score += clearRowItemList.Count;
			}
			if(clearColumnItemList.Count >= CLEAR_UP_NUM){
				result = true;
				foreach(Item itemTmp in clearColumnItemList){
//					yield return StartCoroutine( itemTmp.ClearUp());
					StartCoroutine(itemTmp.ClearUp());
				}
				score += clearColumnItemList.Count;
			}
//			while(item.anim.isPlaying){
//				yield return new WaitForSeconds(0.1f);
//			}
//			yield return 0;
			
			clearRowItemList.Clear();
			clearColumnItemList.Clear();
			return result;
		}
	}
	bool IsField(){
		for(int j = 0;j < COLUMN_NUM;j++){
			if(!itemList[ROW_NUM,j].IsNull()){
				return true;
			}
		}
		return false;
	}
	void ClearUpNull(){
		for(int i = 0;i < ROW_NUM - 1;i++){
			for(int j = 0;j < COLUMN_NUM;j++){
				Item item = itemList[i,j];
				if(item.IsNull()){
					int numNull = 0;
					for(int k = i;k < ROW_NUM - 1;k++){
						if(itemList[k,j].IsNull()){
							numNull++;
						}else{
							break;
						}
					}
					for(int k = i;k < ROW_NUM - 1 && k + numNull < ROW_NUM;k++){
						itemList[k,j].SetItemType(itemList[k + numNull,j].GetItemType());
						itemList[k + numNull,j].SetItemType(Item.ITEM_TYPE.NULL);
					}
					itemList[ROW_NUM - 1,j].SetItemType(Item.ITEM_TYPE.NULL);
				}
			}
		}
	}
	public GameHeroItem GetPlayer(){
		return player;
	}
	public int GetNullRowByColumn(int tColumn){
		for(int i = 0;i < ROW_NUM;i++){
			if(itemList[i,tColumn].IsNull()){
				return i;
			}
		}
		return ROW_NUM;
	}
	public Item GetNullItemByColumn(int tColumn,int index){
		for(int i = 0;i < ROW_NUM + Player_Max_Count;i++){
			if(itemList[i,tColumn].IsNull()){
				return itemList[i + index,tColumn];
			}
		}
		return null;
	}
	public void RePlay(){
		
		gameState = GameState.INIT;
	}
	public void Close(){
		GameManager.GetInstatnce().ShowPanel(PanelName.MissonPanel);
	}
	public void Next(){
		GameManager.GetInstatnce().ShowPanel(PanelName.MissonPanel);
	}
	public void ClearItemList(){
		for(int i = 0;i < ROW_NUM + Player_Max_Count;i++){
			for(int j = 0;j < COLUMN_NUM;j++){
				if(itemList != null && itemList[i,j] != null){
					NGUITools.Destroy(itemList[i,j].gameObject);
				}
			}
		}
	}

	#region implemented abstract members of BasePanel


	public override void Show ()
	{
		throw new System.NotImplementedException ();
	}

	public override void Hide ()
	{
		throw new System.NotImplementedException ();
	}
	#endregion
}
